package com.mpsc.fbpm.consumer.service.impl;


import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.mpsc.fbpm.consumer.config.FBPMProperties;
import com.mpsc.fbpm.consumer.requestBean.*;
import com.mpsc.fbpm.consumer.requestBean.variable.RestVariable;
import com.mpsc.fbpm.consumer.response.BaseResponse;
import com.mpsc.fbpm.consumer.response.FbpmResponseEntity;
import com.mpsc.fbpm.consumer.response.ProcTaskInfo;
import com.mpsc.fbpm.consumer.service.FbpmService;
import com.mpsc.fbpm.consumer.util.FbpmUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class FbpmServiceImpl implements FbpmService {

//    @Value("${batch_create}")
//    private String batchCreate;
//
//    @Value("${batch_approve}")
//    private String batchApprove;
//
//    @Value("${batch_back}")
//    private String batchBack;
//
//    @Value("${batch_cancel}")
//    private String batchCancel;

    @Autowired
    private FBPMProperties fbpmProperties;

    @Autowired
    private RestTemplate restTemplate;


    /**
     * 批量启动流程
     *
     * @param processStart 批量启动流程所需参数
     * @return baseResponse
     */
    @Override
    @Transactional
    public BaseResponse batchProcessInstance(ProcessStartQuery processStart) {
//        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(MediaType.APPLICATION_JSON);
//        HttpEntity<ProcessStartQuery> requestEntity = new HttpEntity<>(processStart, headers);
//        ResponseEntity<BaseResponse<List<FbpmResponseEntity>>> result =
//                restTemplate.exchange(url, HttpMethod.POST,requestEntity, new ParameterizedTypeReference<BaseResponse<List<FbpmResponseEntity>>>(){});
//        BaseResponse<List<FbpmResponseEntity>> response = result.getBody();
        BaseResponse response = restTemplate.postForObject(fbpmProperties.getCreate(), JSON.toJSON(processStart), BaseResponse.class);
//        BaseResponse<List<FbpmResponseEntity>> s =
//                restTemplate.execute(url, HttpMethod.POST, requestEntity, BaseResponse<List<FbpmResponseEntity>>);
        return response;
    }

    /**
     * 批量审核流程
     *
     * @param processApprove 批量审核流程所需参数
     * @return baseResponse
     */
    @Override
    @Transactional
    public BaseResponse batchProcessApprove(ProcessApproveQuery processApprove) {
        BaseResponse response = restTemplate.postForObject(fbpmProperties.getApprove(), JSON.toJSON(processApprove), BaseResponse.class);
        return response;
    }

    /**
     * 批量驳回流程
     *
     * @param processBack 批量审核流程所需参数
     * @return baseResponse
     */
    @Override
    @Transactional
    public BaseResponse batchProcessBack(ProcessBackQuery processBack) {
        BaseResponse response = restTemplate.postForObject(fbpmProperties.getBack(), JSON.toJSON(processBack), BaseResponse.class);
        return response;
    }

    /**
     * 批量撤销流程
     *
     * @param processCancel 批量撤销流程所需参数
     * @return baseResponse
     */
    @Override
    @Transactional
    public BaseResponse batchProcessCancel(ProcessCancelQuery processCancel) {
        BaseResponse response = restTemplate.postForObject(fbpmProperties.getCancel(), JSON.toJSON(processCancel), BaseResponse.class);
        return response;
    }

    /**
     * 查询代办任务
     *
     * @param url       远程访问接口的路径
     * @param taskState 批量审核流程所需参数
     * @return baseResponse
     */
    @Override
    @Transactional
    public BaseResponse selectTaskListByState(String url, TaskStateQuery taskState) {
        BaseResponse response = new BaseResponse();
        url += "?userCode=" + taskState.getAppCode() +
                "&roleId=" + taskState.getRoleId() +
                "&bizTypeCode=" + taskState.getBizTypeCode() +
                "&appCode=" + taskState.getAppCode() +
                "&menuId=" + taskState.getMenuId();
        String json = restTemplate.getForObject(url, String.class);
        List<ProcTaskInfo> procTaskInfo = (List<ProcTaskInfo>) JSON.parse(json);
        response.setCode(200);
        response.setData(procTaskInfo);
        return response;
    }

    /**
     * 查询已办任务
     *
     * @param url        远程访问接口的路径
     * @param taskFinish 批量审核流程所需参数
     * @return baseResponse
     */
    @Override
    @Transactional
    public BaseResponse selectTaskFinishList(String url, TaskFinishQuery taskFinish) {
        BaseResponse response = new BaseResponse();
        url += "?userCode=" + taskFinish.getAppCode() +
                "&bizTypeCode=" + taskFinish.getBizTypeCode() +
                "&appCode=" + taskFinish.getAppCode() +
                "&menuId=" + taskFinish.getMenuId();
        String json = restTemplate.getForObject(url, String.class);
        List<ProcTaskInfo> procTaskInfo = (List<ProcTaskInfo>) JSON.parse(json);
        response.setCode(200);
        response.setData(procTaskInfo);
        return response;
    }

    /**
     * 根据流程实例废弃流程
     *
     * @param url 远程访问接口的路径
     * @return baseResponse
     */
    @Override
    public BaseResponse deleteProcessByBusinessKey(String url) {

        ResponseEntity<BaseResponse> resp = restTemplate.exchange(url, HttpMethod.DELETE, null, BaseResponse.class);
        if (resp.getStatusCode().value() == 200) {
            BaseResponse response = resp.getBody();
            System.out.println(response.getMsg());
        }
        return null;
    }

    /**
     * 批量测试工作流数据
     *
     * @param userCode    用户code
     * @param bizTypeCode 单据类型code
     * @param rgCode      区划code
     * @param num         批量测试数目
     * @return baseResponse
     */
    @Override
    public BaseResponse fbpmBatchTest(String userCode, String bizTypeCode, String rgCode, Integer num) {
        BaseResponse response = new BaseResponse();
        List<String> billList = Lists.newArrayListWithCapacity(num);
        if (num > 0) {
            for (int i = 0; i < num; i++) {
                billList.add(UUID.randomUUID().toString().replace("-", ""));
            }
        }
        long startTime = 0;
        long approveTime = 0;
        long cancelTime = 0;
        long backTime = 0;
        //启动
        ProcessStartQuery startQuery;
        BaseResponse startResponse;
        //审核
        ProcessApproveQuery approveQuery;
        BaseResponse approveResponse;

        ProcessBackQuery backQuery;
        BaseResponse backResponse;
        List<String> taskIdList;
        List<RestVariable> variables = new ArrayList<>();
        //组装工作流批量启动参数
        long l1 = System.currentTimeMillis();
        startQuery = FbpmUtil.getProcessStartQuery(billList, bizTypeCode, rgCode, userCode, variables);
        startTime = System.currentTimeMillis() - l1;
        //批量启动工作流
        startResponse = this.batchProcessInstance(startQuery);
        if (startResponse.getCode() != 100200) {
            System.out.println(startResponse.getMsg());
        }
        List<FbpmResponseEntity> startList = (List<FbpmResponseEntity>) startResponse.getData();
        if (null != startList) {
            taskIdList = startList.stream().map(FbpmResponseEntity::getTaskId).collect(Collectors.toList());
            //批量审核工作流
            approveQuery = FbpmUtil.getProcessApproveQuery(taskIdList, userCode, variables);
            long l2 = System.currentTimeMillis();
            approveResponse = this.batchProcessApprove(approveQuery);
            approveTime = System.currentTimeMillis() - l2;
            if (approveResponse.getCode() == 100200) {
                //批量撤销工作流
                ProcessCancelQuery cancelQuery = FbpmUtil.getProcessCancelQuery(taskIdList, userCode, variables);
                long l3 = System.currentTimeMillis();
                BaseResponse cancelResponse = this.batchProcessCancel(cancelQuery);
                cancelTime = System.currentTimeMillis() - l3;
                if (cancelResponse.getCode() == 100200) {
                    List<FbpmResponseEntity> cancelList = (List<FbpmResponseEntity>) cancelResponse.getData();
                    taskIdList = cancelList.stream().filter(s -> s.getStatusCode().equals("002")).map(FbpmResponseEntity::getTaskId).collect(Collectors.toList());
                    //批量审核工作流
                    approveQuery = FbpmUtil.getProcessApproveQuery(taskIdList, userCode, variables);
                    approveResponse = this.batchProcessApprove(approveQuery);
                    if (approveResponse.getCode() == 100200) {
                        List<FbpmResponseEntity> approveList = (List<FbpmResponseEntity>) cancelResponse.getData();
                        taskIdList = approveList.stream().filter(s -> s.getStatusCode().equals("002")).map(FbpmResponseEntity::getTaskId).collect(Collectors.toList());
                        long l4 = System.currentTimeMillis();
                        backQuery = FbpmUtil.getProcessBackQuery(taskIdList, userCode, variables);
                        backTime = System.currentTimeMillis() - l4;
                        this.batchProcessBack(backQuery);
                    }
                }
            }
        }
        return null;
    }
}
